package cn.lcsjsxy.yxc.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * 1.实例化                    构造器     第一次请求/服务启动      1
 * 2.初始化                    init       构造完毕               1
 * 3.接受请求，处理请求 服务     service    每次请求               多次
 * 4.销毁                     destroy    关闭服务                1
 * <p>
 * Servlet在Tomcat中是单例的
 * Servlet的成员变量在多个线程之中是共享的
 * 不建议在service方法中修改成员变量 在并法请求时，会引发线程安全问题
 * default-servlet用于加载静态资源的servlet，默认随服务器启动，默认启动序号为1
 * <p>
 * servlet继承结构
 * 1.顶级的Servlet接口
 * public interface Servlet{
 * //初始化方法。构造完毕后，由tomcat自动调用完成初始化功能的方法
 * void init(ServletConfig var1) throws ServletException;
 * <p>
 * //获得ServletConfig对象的方法
 * ServletConfig getServletConfig();
 * <p>
 * //接收用户请求，向用户响应信息的方法
 * void service(ServletRequest var1,ServletResponse var2) throws ServletException,IOException;
 * <p>
 * //返回servlet字符串形式描述信息的方法
 * String getServletInfo();
 * <p>
 * //Servlet在回收前，tomcat调用的销毁方法，往往用于做资源的释放工作
 * void destroy();
 * }
 * 2.抽象的类   GenericServlet      侧重service方法以外的其他方法的基础处理
 * public abstract class GenericServlet implements Servlet {
 * private transient ServletConfig config;
 * public void destroy() {
 * //将抽象方法，重写为普通方法，在方法内部没有任何的实现代码
 * //平庸实现
 * }
 * //tomcat在调用init方法时，会读取配置信息进入一个ServletConfig对象，并将该对象传入init方法
 * public void init(ServletConfig config) throws ServletException {
 * //将config对象存储为当前的属性
 * this.config = config;
 * //调用了重载的无参的init
 * this.init();
 * }
 * <p>
 * //重载的初始化方法，我们重写初始化方法时对应的方法
 * public void init() throws ServletException {
 * <p>
 * }
 * <p>
 * //返回ServletConfig的方法
 * ServletConfig getServletConfig() {
 * return this.config;
 * }
 * <p>
 * //再次抽象声明Service方法
 * void service(ServletRequest var1,ServletResponse var2) throws ServletException,IOException；
 * }
 * 3.HttpServlet 抽象类    侧重service方法的处理
 * public abstract class HttpServlet extends GenericServlet {
 * //参数的父转子，调用重载的service方法
 * public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
 * HttpServletRequest request;
 * HttpServletResponse response;
 * try {
 * //参数的父转子
 * request = (HttpServletRequest)req;
 * response = (HttpServletResponse)res;
 * } catch (ClassCastException var6) {
 * throw new ServletException(lStrings.getString("http.non_http"));
 * }
 * //调用重载的service方法
 * this.service(request, response);
 * }
 * <p>
 * <p>
 * protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 * //获取请求的方式
 * switch (req.getMethod()) {  //GET    POST    PUT     DELETE  OPTIONS... ...
 * <p>
 * //根据请求方式调用对应的do...方法
 * case "GET":
 * long lastModified = this.getLastModified(req);
 * if (lastModified == -1L) {
 * this.doGet(req, resp);
 * } else {
 * long ifModifiedSince;
 * try {
 * ifModifiedSince = req.getDateHeader("If-Modified-Since");
 * } catch (IllegalArgumentException var11) {
 * ifModifiedSince = -1L;
 * }
 * <p>
 * if (ifModifiedSince < lastModified / 1000L * 1000L) {
 * this.maybeSetLastModified(resp, lastModified);
 * this.doGet(req, resp);
 * } else {
 * resp.setStatus(304);
 * }
 * }
 * break;
 * case "HEAD":
 * long lastModified = this.getLastModified(req);
 * this.maybeSetLastModified(resp, lastModified);
 * this.doHead(req, resp);
 * break;
 * case "POST":
 * this.doPost(req, resp);
 * break;
 * case "PUT":
 * this.doPut(req, resp);
 * break;
 * case "DELETE":
 * this.doDelete(req, resp);
 * break;
 * case "OPTIONS":
 * this.doOptions(req, resp);
 * break;
 * case "TRACE":
 * this.doTrace(req, resp);
 * break;
 * case "PATCH":
 * this.doPatch(req, resp);
 * break;
 * default:
 * String errMsg = lStrings.getString("http.method_not_implemented");
 * Object[] errArgs = new Object[1];
 * errArgs[0] = method;
 * errMsg = MessageFormat.format(errMsg, errArgs);
 * resp.sendError(501, errMsg);
 * }
 * }
 * <p>
 * //故意响应405
 * protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 * String msg = lStrings.getString("http.method_get_not_supported");
 * //故意响应 405 请求方式不允许的信息
 * this.sendMethodNotAllowed(req, resp, msg);
 * }
 * <p>
 * protected void doPatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 * String msg = lStrings.getString("http.method_patch_not_supported");
 * //故意响应405,请求方式不允许的信息
 * this.sendMethodNotAllowed(req, resp, msg);
 * }
 * }
 * <p>
 * 4.自定义Servlet
 * class Servlet1 extends HttpServlet {
 * protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 * //接收用户请求信息
 * <p>
 * //作出响应
 * }
 * }
 * <p>
 * 》部分程序员推荐在servlet中重写doXxx方法处理请求  理由：service方法中可能提供了一些处理，如果我们直接重写service的话，父类中service方法处理的功能则失效
 * 》目前直接重写service也没有什么问题
 * 》后续使用了SpringMVC框架后，我们无需继承HttpServlet，处理请求的方法也无需是doXxx service
 * 》如果doGet和doPost方法中我们定义的代码的都一样，可以让一个方法直接调用另一个方法
 * 掌握的技能
 * 继承HttpServlet后，要么重写service方法，要么重写   doGet/doPost
 */
@WebServlet(value = "/servletLifeCycle", loadOnStartup = 100)
public class ServletLifeCycle extends HttpServlet {
    public ServletLifeCycle() {
        System.out.println("构造器");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("初始化");
    }

//    @Override
//    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("服务");
//    }


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post");
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}
